package com.xiyoo.cw.utils;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Random;
import java.util.UUID;

/**
 * @Description
 * @Author zhouzhongqing
 * @Date 2024/2/20 17:06
 * @Version 1.0
 **/
public class AESUtil {

    private static final String AES_ALGORITHM = "AES/CBC/PKCS5Padding";

    /**
     * 加密字符串
     *
     * @param content 需要加密的字符串
     * @param key     密钥，长度必须为 16 的倍数
     * @param iv      初始化向量，长度必须为 16
     * @return 加密后的字符串
     */
    public static String encrypt(String content, String key, String iv) {
        try {
            byte[] contentBytes = content.getBytes(StandardCharsets.UTF_8);
            SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");
            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8));
            Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec);
            byte[] encryptedBytes = cipher.doFinal(contentBytes);
            return Base64.getEncoder().encodeToString(encryptedBytes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 解密字符串
     *
     * @param content 需要解密的字符串
     * @param key     密钥，长度必须为 16 的倍数
     * @param iv      初始化向量，长度必须为 16
     * @return 解密后的字符串
     */
    public static String decrypt(String content, String key, String iv) {
        try {
            byte[] encryptedBytes = Base64.getDecoder().decode(content);
            SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");
            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8));
            Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);
            byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
            return new String(decryptedBytes, StandardCharsets.UTF_8);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 用于生成16位的随机数 iv
     *
     * @return
     */
    public static String getRandomStringIv() {
        String base = "abcdefghijklmnopqrstuvwxyz0123456789";
        Random random = new Random();
        StringBuilder key = new StringBuilder();
        for (int i = 0; i < 16; i++) {
            int keyNumber = random.nextInt(base.length());
            key.append(base.charAt(keyNumber));
        }
        return key.toString();
    }

    /**
     * 用于生成一组16位随机数 key
     *
     * @return
     */
    public static String getRandomStringKey() {
        int hashCodeValue = UUID.randomUUID().hashCode();
        if (hashCodeValue < 0) {
            hashCodeValue = -hashCodeValue;
        }
        //左边补0,16位，进制（d,x）
        return String.format("%016d", hashCodeValue);
    }

    public static void main(String[] args) {
        // 32 字节的密钥
        String key = getRandomStringKey();
        // 16 字节的初始化向量
        String iv = getRandomStringIv();
        // 需要加密的字符串
        String content = "admin123456";

        String encryptedContent = AESUtil.encrypt(content, key, iv);
        System.out.println("Encrypted Content: " + encryptedContent);

        String decryptedContent = AESUtil.decrypt(encryptedContent, key, iv);
        System.out.println("Decrypted Content: " + decryptedContent);
    }
}
